<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>依赖调用分析报告</title>
    <style>
      .header{
        display: flex;
        margin: 10px 0px;
      }
      .header:hover{
        cursor: default;
      }
      .title{
        font-size: 24px;
        width: 690px;
        display: flex;
      }
      .description {
        display: flex;
        margin: auto 0px;
        color: #817e7e;
        padding-top: 8px;
      }
      .main{
        margin-bottom: 30px;
      }
      .name {
        color: green;
        width: 250px;
        text-align: center;
      }
      .main_area{
        display: flex; 
        width: 100%; 
        border-top: 2px solid #d81414;
      }
      .api_area{
        margin:auto 0px;
      }
      .second {
        display: flex;
        padding-bottom: 10px;
      }
      .owner {
        color: #000000;
        display: flex;
        width: 400px;
        min-width: 400px;
        padding: 4px;
        margin-right: 10px;
        height: 26px;
        white-space: nowrap;
        overflow-x: auto;
        overflow-y: hidden;
      }
      .owner:hover {
        cursor: default;
        opacity: 0.9;
      }
      .gray-card {
        margin-left: 10px;
        margin-top: 10px;
        background-color: gray;
        padding: 5px;
        color: #ffffff;
        white-space: nowrap;
      }
      .gray-card:hover {
        cursor: pointer;
        opacity: 0.8;
      }
      .area {
        display: flex;
        max-width: 1050px;
        flex-wrap: wrap;
        margin-top: -10px;
        overflow: auto;
      }
      .area_detail {
        display: flex;
        max-width: 3050px;
        flex-wrap: wrap;
        margin-top: -10px;
        padding: 20px;
      }
      #api_detail_grey {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        z-index: 2;
        text-align: center;
        margin: 0;
        border: 0;
        padding: 0;
        display: none;
      }
      .back-gray{
        position: absolute;
        top:0;
        left: 0;
        width: 100%;
        height: 100%;
        background-color: gray;
        opacity: 0.3;
        z-index: -1;
      }
      .api_detail_content {
        margin: 200px auto 0px;
        width: 800px;
        height: 360px;
        border: 1px solid gray;
      }
      .api_detail_header {
        width: 100%;
        height: 60px;
        background-color: rgb(112, 117, 190);
      }
      .api_detail_title {
        float: left;
        height: 20px;
        text-align: left;
        width: 400px;
        margin-top: 20px;
        margin-right: 10px;
        margin-left: 20px;
        color: #fff;
      }
      .api_detail_closeBtn {
        float: right;
        height: 20px;
        width: 50px;
        margin-top: 20px;
        margin-right: 10px;
        color: #fff;
      }
      .api_detail_closeBtn:hover {
        cursor: pointer;
      }
      #parse_error_detail {
        clear: both;
        background-color: rgb(206, 197, 197);
        width: 100%;
        height: 300px;
        overflow-y: scroll;
      }
      .card {
        margin-left: 10px;
        margin-top: 10px;
        background-color: rgb(69, 170, 238);
        padding: 5px;
        color: #ffffff;
        white-space: nowrap;
      }
      .card:hover {
        cursor: default;
      }
      .version-card {
        margin-left: 10px;
        margin-top: 10px;
        background-color: rgb(238 163 69);
        padding: 5px;
        color: #ffffff;
        white-space: nowrap;
      }
      .version-card:hover {
        cursor: default;
      }
      #methodMap, #apiMap, #browserMap, #typeMap, #parseErrorInfos, #versionMap {
        padding-top: 10px;
        border-left: 2px solid #d81414;
        padding-left: 10px;
      }
      .noContent{
        height:26px; 
        padding: 4px 4px 10px 4px;
      }
      .score_area{
        border-top: 2px solid #d81414;
      }
      #scoreNum {
        display: flex;
        height: 58px;
        line-height: 58px;
      }
      .left_score_title{
        text-align: center;
        color:rgb(13, 52, 226);
        min-width: 250px;
      }
      .left_score_title:hover{
        cursor: default;
      }
      .left_score_num{
        border-left: 2px solid #d81414;
        padding-left: 10px;
      }
      .left_score_num:hover{
        cursor: default;
      }
      #scoreMessage {
        display: flex;
        border-top: 2px solid #d81414;
      }
      .left_message{
        text-align: center;
        color:rgb(13, 52, 226);
        min-width: 250px;
        line-height: 58px;
        border-right: 2px solid #d81414;
      }
      .left_message:hover{
        cursor: default;
      }
      .right_message{
        color: gray;
        padding-left: 10px;
      }
      .right_message:hover{
        cursor: default;
      }
      .line_message{
        padding-bottom: 5px;
      }
      .name:hover {
        cursor: default;
      }
      #reportTitle {
        max-width: 500px;
        white-space: nowrap;
        text-overflow: ellipsis;
        overflow: hidden;
      }
      #reportTime {
        margin-left:5px;
        font-size:16px;
        color:gray;
        padding-top:12px;
      }
      .asStyle {
        color: #3e3cea;
        margin-left: 5px;
        margin-top: -1px;
        font-weight: bold;
      }
      .httpReopBtn:hover{
        cursor: pointer;
      }
    </style>
  </head>
  <body>
    <div class="header">
      <div class="title"><div id="reportTitle"></div><div id="reportTime"></div></div>
      <div class="description">
        <span style="color:green;">tips：</span>红色字体表示黑名单API，<span style="color:green;margin-right:2px;">( )</span>中数字表示API调用次数，<span style="color:green;margin-right:2px;">-> </span>表示存在AS映射，<span style="color:green;margin-right:2px;">[ ]</span>中数字表示API所在文件代码行（配置httpRepo可跳转）
      </div>
    </div>
    <div class="main">
      <!--methodMap -->
      <div class="main_area">
        <div class="api_area">
          <div class="name">Method APIS：</div>
        </div>
        <div id="methodMap">
          <!-- -->
        </div>
      </div>
      <!--typeMap -->
      <div class="main_area">
        <div class="api_area">
          <div class="name">Type APIS：</div>
        </div>
        <div id="typeMap">
          <!-- -->
        </div>
      </div>
      <!--apiMap -->
      <div class="main_area">
        <div class="api_area">
          <div class="name">未分类 APIS：</div>
        </div>
        <div id="apiMap">
          <!-- -->
        </div>
      </div>
      <!--browserMap -->
      <div class="main_area">
        <div class="api_area">
          <div class="name">Browser APIS：</div>
        </div>
        <div id="browserMap">
          <!-- -->
        </div>
      </div>
      <!--noParseArea -->
      <div class="main_area">
        <div class="api_area">
          <div class="name" style="color:rgb(13, 52, 226);">解析异常：</div>
        </div>
        <div id="parseErrorInfos">
          <!-- -->
        </div>
      </div>
      <!--versionMap -->
      <div class="main_area" id="versionArea">
        <div class="api_area">
          <div class="name" style="color:rgb(13, 52, 226);">依赖版本：</div>
        </div>
        <div id="versionMap">
          <!-- -->
        </div>
      </div>
      <!--scoreArea -->
      <div class="score_area">
        <div id="scoreNum"></div>
        <div id="scoreMessage">
          <!-- -->
        </div>
      </div>
    </div>

    <!--蒙层Dialog-->
    <div id="api_detail_grey">
      <div class="back-gray" onclick="api_hide()"></div>
      <div class="api_detail_content">
        <div class="api_detail_header">
          <div class="api_detail_title"></div>
          <div class="api_detail_closeBtn" onclick="api_hide()">关闭</div>
        </div>
        <div id="parse_error_detail"></div>
      </div>
    </div>

    <script src="./index.js"></script>
    <script>
      // 隐藏蒙层
      function api_hide() {
        document.getElementById('api_detail_grey').style.display = 'none';
        document.getElementsByClassName('api_detail_title').innerText = '';
      }
      // 展示蒙层
      function api_show(event) {
        const module = event.target.getAttribute('data-f');
        const stackMessage = report.parseErrorInfos[module].stack;
        noParseDetails(stackMessage);
        document.getElementsByClassName('api_detail_title')[0].innerText = report.parseErrorInfos[module].file;
        document.getElementById('api_detail_grey').style.display = 'block';
      }
      // 点击解析失败详情处理
      function noParseDetails(stackMessage) {
        var html = '';
        html = html + '<div class="area_detail" style="text-align:left;">';
        html = html + stackMessage;
        html = html + '</div>';
        document.getElementById('parse_error_detail').innerHTML = html;
      }
      // 处理版本依赖渲染
      function versionRender() {
        if(report.versionMap && Object.keys(report.versionMap).length>0){
          var data = report.versionMap;
          var html = '';
          Object.keys(data).forEach(element => {
            html = html + '<div class="second"><div class="owner"';
            html = html + ' >';
            html = html + element;
            html = html + '</div><div class="area">';
            data[element].callSource.forEach(selement => {
              html = html + '<div class="version-card">';
              html = html + selement;
              html = html + '</div>';
            });
            html = html + '</div></div>';
          });
          if(html ==''){
            document.getElementById('versionMap').innerHTML ='<div class="noContent">-</div>';
            return;
          }
          document.getElementById('versionMap').innerHTML = html;
        }else{
          document.getElementById('versionArea').style.display = 'none';
        }
      }
      // 处理parseErrorInfos
      function doParseError() {
        var html = '';
        if(report.parseErrorInfos.length >0){
          html = html + '<div class="second"><div class="owner">-</div><div class="area">';
          report.parseErrorInfos.forEach((element, index) => {
            html = html + '<div class="gray-card';
            html = html + '" onclick="api_show(event)" data-f="';
            html = html + index;
            html = html + '">';
            html = html + '<span style="color:#e9eb0c;">';
            html = html + element.projectName;
            html = html + ' : ';
            html = html + '</span>';
            html = html + element.file;
            html = html + ' ( 点击查看错误详情 ) ';
            html = html + '</div>';
          });
          html = html + '</div></div>';
        }
        if(html ==''){
          document.getElementById('parseErrorInfos').innerHTML ='<div class="noContent">-</div>';
          return;
        }
        document.getElementById('parseErrorInfos').innerHTML = html;
      }
      // 展示分数及代码建议
      function doScore(){
        var data = report.scoreMap;
        var leftHtml ='<div class="left_score_title">代码得分：</div><div class="left_score_num">';
        leftHtml = leftHtml + data.score;
        leftHtml = leftHtml + ' 分';
        document.getElementById('scoreNum').innerHTML = leftHtml;

        if(data.message.length>0){
          var html ='<div class="left_message">优化建议：</div>';
          html = html + '<div class="right_message">';
          html = html + '<div style="height:18px;"></div>';
          data.message.forEach((mes, index)=>{
            html = html + '<div class="line_message">';
            html = html + (index+1);
            html = html + '.  ';
            html = html + mes;
            html = html + '</div>';
          })
          html = html + '</div>';
          document.getElementById('scoreMessage').innerHTML = html;
        }
      }
      // 渲染API表格区域
      function renderApiTable(data, type) {
        var html = '';
        Object.keys(data).forEach(element => {
          html = html + '<div class="second"><div class="owner"';
          if(data[element].isBlack){
            html = html + ' style="color:red"';
          }
          html = html + ' >';
          html = html + element;
          html = html + ' ( ';
          html = html + data[element].callNum;
          html = html + ' ) ';
          if(data[element].callOrigin){
            html = html + '<span class="asStyle">';
            html = html + '-> ';
            html = html + data[element].callOrigin;
            html = html + '</span>';
          }
          html = html + '</div><div class="area">';
          Object.keys(data[element].callFiles).forEach(selement => {
            html = html + '<div class="card">';
            html = html + '<span style="color:#e9eb0c;">';
            html = html + data[element].callFiles[selement].projectName;
            html = html + ' : ';
            html = html + '</span>';
            html = html + selement.split('&')[1];
            html = html + ' : [ ';
              const lineTemp = data[element].callFiles[selement].lines;
              const httpRepo = data[element].callFiles[selement].httpRepo || '';
              for(let i=0; i<lineTemp.length; i++){
                if(httpRepo){
                  html = html + '<a class="httpReopBtn" href="';
                  html = html + httpRepo;
                  html = html + selement.split('&')[1];
                  html = html + '#L';
                  html = html + lineTemp[i];
                  html = html + '" target="_blank">';
                  html = html + lineTemp[i];
                  html = html + '</a>';
                }else{
                  html = html + lineTemp[i];
                }
                if(i<lineTemp.length-1){
                  html = html + ' , ';
                }
              }
            html = html + ' ] ';
            html = html + '</div>';
          });
          html = html + '</div></div>';
        });
        if(html ==''){
          document.getElementById(type).innerHTML ='<div class="noContent">-</div>';
          return;
        }
        document.getElementById(type).innerHTML = html;
      }
      // 入口函数
      function main() {
        // render header
        document.title = report.reportTitle || '依赖调用分析报告';
        document.getElementById('reportTitle').innerText = report.reportTitle || '依赖调用分析报告';
        document.getElementById('reportTime').innerText = ' (' + report.analysisTime + ') ';
        // render api
        if(report.mapNames && report.mapNames.length>0){
          report.mapNames.forEach((item)=>{
            renderApiTable(report[item], item);
          })
        }
        doParseError();
        versionRender();
        if(report.scoreMap){
          doScore();
        }else{
          document.getElementById('scoreNum').style.display = 'none';
          document.getElementById('scoreMessage').style.display = 'none';
        }
      }

      main();

    </script>
  </body>
</html>
